/*
 * dataset.cc
 *
 *  Created on: Jun 1, 2011
 *      Author: tqlong
 */

#include <cassert>
#include <fstream>
#include "dataset.h"

void
Dataset::load(const std::string& fName)
{
  std::ifstream f(fName.c_str());
  std::string type;
  std::getline(f, type);
  f >> n_ >> d_;
  std::cout << "load " << fName << " type=" << type << " n=" << n_ << " d="
      << d_ << std::endl;
  if (type == "TXT")
    {
      std::getline(f, type);
      this->resize(n_);
      // std::cout << "size=" << size() << std::endl;
      for (int i = 0; i < n_; i++)
        {
          this->at(i).load(f, arma::arma_ascii);
        }
    }
  assert((int)size() == n_);
  f.close();
}

void
Dataset::save(const std::string& fName)
{
  std::ofstream f(fName.c_str());
  f << "TXT" << std::endl << n_ << std::endl << d_ << std::endl;
  for (int i = 0; i < n_; i++)
    {
      this->at(i).save(f, arma::arma_ascii);
    }
  f.close();
}

void
Dataset::generate(int n, int dim, int type, const vec& p1, const vec& p2)
{
  std::cout << "generate n=" << n << " dim=" << dim << " type=" << type
      << "\np1=" << p1 << "\np2=" << p2 << std::endl;
  assert((int)p1.n_elem == dim && (int)p2.n_elem == dim);
  this->resize(n);
  n_ = n;
  d_ = dim;
  vec std;
  switch (type)
    {
  case RANDU: // uniform
    for (int i = 0; i < n; i++)
      {
        this->at(i) = p1 + (arma::randu<vec>(dim) % p2) - (p2 / 2);
      }
    break;
  case RANDN:
    std = p2;
    for (int d = 0; d < dim; d++)
      std[d] = sqrt(p2[d]);
    for (int i = 0; i < n; i++)
      {
        this->at(i) = p1 + (arma::randn<vec>(dim) % std);
      }
    break;
  default:
    std::cout << "Unrecognized random type = " << type << std::endl;
    }
}
